import socket
import struct
import time
import logging


logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
multicastPort = 5004
source_port = 4999
multicastAddress = "224.0.0.10"
isMultiCasting = False
isRegisterCasting = False
tag = "MultiCastManager"




def log(tag,msg):
    print(f"{tag},{msg}")



def startMultiCast(msg:str):
    log(tag,"startMultiCast")
    sock = getSocket()
      # 绑定到指定的源端口号
    sock.bind(('', source_port))
    isMultiCasting = True
    while isMultiCasting:
        try:
            sendMultiCastData(sock,msg,multicastAddress,multicastPort)
            time.sleep(0.5)
        except Exception as e:
            log(tag,f"sendMultiCastData fail:{e.args}")
            isMultiCasting = False
    sock.close()
        


   
def sendMultiCastData(sock:socket, msg:str,multiCastAddress:str,multiCastPort:int = 1000):
      log(tag,f"sendMultiCastData:{msg}")
      log(tag,f"sendMultiCastData encode:{msg.encode()}")
      sock.sendto(msg.encode(), (multiCastAddress, multiCastPort))
      log(tag,f"sendMultiCastData success")
 
def getSocket():
    sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    ttl = struct.pack('b',2)
    sock.setsockopt(socket.IPPROTO_IP,socket.IP_MULTICAST_TTL,ttl)
    log(tag,"getSocket")
    return sock

def registerMultiCast(port =multicastPort):
    logging.debug("registerMultiCast")
    isRegisterCasting = True
    sock = getSocket()
    server_address = ('', port)
    sock.bind(server_address)
    group = socket.inet_aton(multicastAddress)
    mreq = struct.pack('4sl',group,socket.INADDR_ANY)
    sock.setsockopt(socket.IPPROTO_IP,socket.IP_ADD_MEMBERSHIP,mreq)
    try:
      logging.debug("Waiting for messages from the multicast group...")
      while isRegisterCasting:
        data,address = sock.recvfrom(2048)
        logging.debug(f"address:{address}--data:{data}")
    finally:
        sock.close()    




if __name__ == "__main__":
    logging.debug("main")
    code = int(input("enter code: 1: startMultiCast; 2:registerMultiCast    :  "))
    logging.debug(f"code:{code}")
    match code:
        case 1:
            msg = '{"version":1,"deviceId":"03:06:09:0A:0F:0E","deviceName":"tangdekun PC111","deviceAddress":null,"deviceTypeId":"06","brandId":"04","productCode":"0003","service":[1],"serviceInfoList":[{"serviceId":1,"serviceName":"SERVICE_PARCEL_DROP","servicePort":10098,"serviceData":null}]}'
            startMultiCast(msg)
        case 2:
            registerMultiCast()
        case _ :
            logging.debug("inval code")
    
